Skip to content

Optimizer misc improvements - #26704

Open
SolalPirelli wants to merge 4 commits into
scala:mainfrom
dotty-staging:solal/optimizer-bounce
Open

Optimizer misc improvements#26704
SolalPirelli wants to merge 4 commits into
scala:mainfrom
dotty-staging:solal/optimizer-bounce

Conversation

@SolalPirelli

@SolalPirelli SolalPirelli commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

In support of the bounce benchmark (source):

  • Recognize loads from scala/package$ (non-null, no side effects)
  • Recognize applyVoid as a specialization of apply for functions
  • Stop making a list of which module loads can be elided and just use scala/*

With this, we can inline all foreach calls and we don't need an IntRef

Have you relied on LLM-based tools in this contribution?

No

How was the solution tested?

New automated tests (including the issue's reproducer, if applicable)

@mbovel

mbovel commented Aug 4, 2026

Copy link
Copy Markdown
Member

Benchmarks started. Workflow run.

@mbovel

mbovel commented Aug 5, 2026

Copy link
Copy Markdown
Member

Benchmarks completed. Overview.

@SolalPirelli

Copy link
Copy Markdown
Contributor Author

kmeans has already shown bimodal behavior before. I'll look into what the optimizer does there but that can be a separate PR.

@SolalPirelli
SolalPirelli marked this pull request as ready for review August 5, 2026 14:35
@SolalPirelli
SolalPirelli requested a review from lrytz August 5, 2026 14:35
private val modulesAllowSkipInitialization =
if settings.optAllowSkipCoreModuleInit then optimizerUtils.modulesAllowSkipInitialization else Set.empty
private val modulesAllowSkipInitialization: InternalName => Boolean =
if settings.optAllowSkipCoreModuleInit then n => n.startsWith("scala/") else Set.empty

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd personally still go for a whitelist.. we don't know what will be added to the library in the future, and there can be user-defined code in a scala package.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Although user-defined code in the scala package isn't a supported scenario AFAIK (e.g., Seb pointed out that it would in theory prevent us from ever adding new stdlib classes since they could conflict)

Comment thread compiler/src/dotty/tools/backend/jvm/opt/OptimizerUtils.scala Outdated
Comment thread compiler/src/dotty/tools/backend/jvm/opt/OptimizerUtils.scala Outdated
// invokespecial has, well, special semantics that depend on the class it's being invoked in, see, e.g., https://stackoverflow.com/a/8950564
if (!allowPrivateCalls && i.getOpcode == Opcodes.INVOKESPECIAL && mi.name != BCodeUtils.INSTANCE_CONSTRUCTOR_NAME) {
if (mi.owner == ScalaPackage) {
// Ignore calls that, e.g., load the Range module -- that's still part of a forwarder

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also seems too broad. Also, how is the Scala package object involved in loading the Range module?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how new this is, but you can load modules from the package object now. This is what it contains on main:

solal@LAMP-C007400M scala3 % javap ./library/target/scala-library-bootstrapped/classes/scala/package$.class
Compiled from "package.scala"
public final class scala.package$ {
  public static final scala.package$ MODULE$;
  public static {};
  public scala.Specializable AnyRef();
  public scala.collection.Iterable$ Traversable();
  public scala.collection.Iterable$ Iterable();
  public scala.collection.immutable.Seq$ Seq();
  public scala.collection.immutable.IndexedSeq$ IndexedSeq();
  public scala.collection.Iterator$ Iterator();
  public scala.collection.immutable.List$ List();
  public scala.collection.immutable.Nil$ Nil();
  public scala.collection.immutable.$colon$colon$ $colon$colon();
  public scala.collection.package$$plus$colon$ $plus$colon();
  public scala.collection.package$$colon$plus$ $colon$plus();
  public scala.collection.immutable.Stream$ Stream();
  public scala.collection.immutable.LazyList$ LazyList();
  public scala.collection.immutable.Vector$ Vector();
  public scala.collection.mutable.StringBuilder$ StringBuilder();
  public scala.collection.immutable.Range$ Range();
  public scala.math.BigDecimal$ BigDecimal();
  public scala.math.BigInt$ BigInt();
  public scala.math.Equiv$ Equiv();
  public scala.math.Fractional$ Fractional();
  public scala.math.Integral$ Integral();
  public scala.math.Numeric$ Numeric();
  public scala.math.Ordered$ Ordered();
  public scala.math.Ordering$ Ordering();
  public scala.util.Either$ Either();
  public scala.util.Left$ Left();
  public scala.util.Right$ Right();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a check that it's within the side-effect-free whitelist

@SolalPirelli
SolalPirelli force-pushed the solal/optimizer-bounce branch from 5d4d38e to 3613634 Compare August 14, 2026 11:02
@SolalPirelli
SolalPirelli requested a review from lrytz August 14, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants